package com.code.wordhelper.utils;

import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.FileOutputStream;
import java.util.List;

public class TableTools {
    public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
        //复制单元格内容到第一个单元格
        XWPFTableCell topCell = table.getRow(row).getCell(fromCell);
        for (int cellIndex = fromCell + 1; cellIndex <= toCell; cellIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            List<XWPFParagraph> paragraphs = cell.getParagraphs();
            for (int i = 0; i < paragraphs.size(); i++) {
                topCell.getCTTc().getPList().add(paragraphs.get(i).getCTP());
                topCell.addParagraph(paragraphs.get(i));
            }
        }

        for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            if (cellIndex == fromCell) {
                cell.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
        int rowNr = 0;
        for (XWPFTableRow tableRow : table.getRows()) {
            table.getCTTbl().setTrArray(rowNr++, tableRow.getCtRow());
        }
        //复制单元格内容到第一个单元格
        XWPFTableCell topCell = table.getRow(fromRow).getCell(col);

//        for (int rowIndex = fromRow + 1; rowIndex < toRow; rowIndex++) {
//            XWPFTableCell cell = table.getRow(rowIndex).getTableCells().get(col);
//            List<XWPFParagraph> paragraphs = cell.getParagraphs();
//            if (CollectionUtils.isEmpty(paragraphs)) {
//                continue;
//            }
//            for (int i = 0; i < paragraphs.size(); i++) {
//                if (StringUtils.isEmpty(paragraphs.get(i).getText())) {
//                    continue;
//                }
//                topCell.getCTTc().getPList().add(paragraphs.get(i).getCTP());
//                topCell.addParagraph(paragraphs.get(i));
//            }
//        }

        for (int rowIndex = fromRow; rowIndex < toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            if (rowIndex == fromRow) {
                CTTcPr ctTcPr = cell.getCTTc().getTcPr();
                if(ctTcPr==null){
                    ctTcPr = cell.getCTTc().addNewTcPr();
                }
                ctTcPr.addNewVMerge().setVal(STMerge.RESTART);
            } else {
                CTTcPr ctTcPr = cell.getCTTc().getTcPr();
                if(ctTcPr==null){
                    ctTcPr = cell.getCTTc().addNewTcPr();
                }
                cell.getCTTc().getTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
     * 拆分单元格
     *
     * @param table
     * @param row   第几行
     * @param col   第几列
     * @param num   拆分几行
     */
    public static void splitCellsVertically(XWPFTable table, int row, int col, int num) throws Exception {
        boolean existSplit = false;
        int mergeNum = 0;

        for (int i = row; i < row + num; i++) {
            XWPFTableRow tableRow = table.getRow(i);
            if (tableRow == null) {
                existSplit = false;
                break;
            }
            CTTcPr ctTcPr = tableRow.getCell(col).getCTTc().getTcPr();
            if (ctTcPr != null && ctTcPr.isSetVMerge()) {
                existSplit = true;
                mergeNum++;
            }
        }

        if (existSplit) {
            if (existSplit && mergeNum == num) {
                //修改VMERGE
                for (int i = row; i < row + num; i++) {
                    XWPFTableCell cell = table.getRow(i).getCell(col);
                    cell.getCTTc().getTcPr().getVMerge().unsetVal();
                    cell.getCTTc().getTcPr().unsetVMerge();
                    System.out.println(cell.getCTTc().getTcPr().isSetVMerge());
                }
            } else {
                System.out.println("拆分单元格与本单元格数量不相符");
            }
        } else {
            for (int i = 1; i < num; i++) {
                XWPFTableRow newRow = table.createRow();
                newRow.getCtRow().setTrPr(table.getRow(row).getCtRow().getTrPr());

                copyRow(newRow, table.getRow(row));

                CTRow newCTRrow = CTRow.Factory.parse(newRow.getCtRow().newInputStream());
                XWPFTableRow tableRow = new XWPFTableRow(newCTRrow, table);
                table.addRow(tableRow, i + row);
                table.removeRow(table.getNumberOfRows() - 1);
            }


            //合并此列之外的列
            for (int i = 0; i < table.getRow(row).getTableCells().size(); i++) {
                if (col == i) {
                    continue;
                }

                mergeCellsVertically(table, i, row, row + num);
            }
        }
        int rowNr = 0;
        for (XWPFTableRow tableRow : table.getRows()) {
            table.getCTTbl().setTrArray(rowNr++, tableRow.getCtRow());
        }
    }

    private static void copyRow(XWPFTableRow targetRow, XWPFTableRow sourceRow) {
        targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
        List<XWPFTableCell> tableCells = sourceRow.getTableCells();
        if (CollectionUtils.isEmpty(tableCells)) {
            return;
        }
        for (int i = 0; i < sourceRow.getTableCells().size(); i++) {
            XWPFTableCell sourceCell = sourceRow.getCell(i);
            XWPFTableCell newCell = targetRow.getCell(i);
            newCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
            List<XWPFParagraph> sourceParagraphs = sourceCell.getParagraphs();
            if (CollectionUtils.isEmpty(sourceParagraphs)) {
                continue;
            }
            XWPFParagraph sourceParagraph = sourceParagraphs.get(0);
            List<XWPFParagraph> targetParagraphs = newCell.getParagraphs();
            if (CollectionUtils.isEmpty(targetParagraphs)) {
                XWPFParagraph p = newCell.addParagraph();
                p.getCTP().setPPr(sourceParagraph.getCTP().getPPr());
                XWPFRun run = p.getRuns().isEmpty() ? p.createRun() : p.getRuns().get(0);
                run.setFontFamily(CollectionUtils.isEmpty(sourceParagraph.getRuns()) ? sourceParagraph.createRun().getFontFamily() : sourceParagraph.getRuns().get(0).getFontFamily());
            } else {
                XWPFParagraph p = targetParagraphs.get(0);
                p.getCTP().setPPr(sourceParagraph.getCTP().getPPr());
                XWPFRun run = p.getRuns().isEmpty() ? p.createRun() : p.getRuns().get(0);
                run.setFontFamily(CollectionUtils.isEmpty(sourceParagraph.getRuns()) ? sourceParagraph.createRun().getFontFamily() : sourceParagraph.getRuns().get(0).getFontFamily());
            }
        }
    }

    public static void main(String[] args) throws Exception {
        OPCPackage pack = POIXMLDocument.openPackage("C:\\Users\\10419\\Desktop\\test.docx");
        XWPFDocument document = new XWPFDocument(pack);//创建word对象

        splitCellsVertically(document.getTableArray(0), 2, 0, 10);
        splitCellsVertically(document.getTableArray(0), 2, 1, 10);
        splitCellsVertically(document.getTableArray(0), 2, 2, 10);
//        mergeCellsVertically(document.getTableArray(0), 1, 1, 11);
//        mergeCellsVertically(document.getTableArray(0), 2, 1, 10);
//        mergeCellsVertically(document.getTableArray(0), 3, 1, 10);

        FileOutputStream fos = new FileOutputStream("C:\\Users\\10419\\Desktop\\test1111.docx");
        document.write(fos);
        fos.close();
    }
}
